import {Component, ElementRef, Input, OnDestroy, OnInit, Output, ViewEncapsulation} from '@angular/core';
import {fromEvent,} from "rxjs";
import {debounceTime} from "rxjs/operators";
import {length} from "../../../support/length";
import {animate, state, style, transition, trigger} from "@angular/animations";
import {Cell, CellType, Rect} from "./table.model";
import {FieldDefinition} from "../field/field.definition";
import {Field} from "../field/field.model";
import {CellComponent} from "./cell/cell.component";
import {AppService} from "../../../app.service";
import {BaseComponent} from "../../../support/base.component";


@Component({
  selector: 'ss-platform-table',
  templateUrl: 'table.component.html',
  styleUrls: ['table.component.scss'],
  encapsulation: ViewEncapsulation.None,
  animations: [
    trigger("fade", [
      state("void", style({opacity: 0})),
      state("*", style({opacity: 1})),
      transition("void <=> *", animate(200))
    ])
  ],
  host: {class: "ss-platform-table-wraper"}
})
export class TableComponent extends BaseComponent implements OnInit, OnDestroy {


  CellType: typeof CellType = CellType;

  // 允许编辑
  @Input("ss-edit")
  isEdit: boolean = false;
  // 批量操作
  @Input("ss-batch")
  isBatchOperation: boolean = false;
  // 紧凑显示
  @Input("ss-compact")
  isCompact: boolean = false;
  // 尺寸
  @Input("ss-rect")
  rect: Rect = new Rect();
  // 字段
  @Input("ss-fields")
  fields: Array<Field> = [];
  // 记录
  @Input()
  items: Array<any> = [];
  // 自定义
  cells: Array<Cell> = [];
  cellsHash: any = {};
  // Resize 事件卸载
  unSubscription: any;
  // 字段
  fieldDefinition: any = FieldDefinition;
  // Table  Element
  element: HTMLElement;

  constructor(private elementRef: ElementRef, public $app: AppService) {
    super();
    this.unSubscription = fromEvent(window, "resize").pipe(debounceTime(180)).subscribe(value => {
      this.resize();
    });
  }

  // 初始化
  ngOnInit(): void {
    let self = this;
    self.element = self.elementRef.nativeElement;
    // 初始化列
    if (!self.cells.length) {
      self.fields.forEach(field => self.cells.push(Cell.generateNew(CellType.data, field)));
    }
    self.reset();
    setTimeout(() => self.resize());
  }

  /**
   * 窗口大小改变
   */
  resize(): void {
    let self = this;
    self.rect.width = self.element.clientWidth;
    self.rect.height = self.element.clientHeight;
    if (self.isEdit) {
      self.items = [];
      let rowCount = Math.round((self.rect.height - 74) / 44) + 1;
      for (let i = 0; i < rowCount; i++) {
        self.items.push({});
      }
    }
  }

  /**
   * 重置数据
   */
  reset(): void {
    let self = this,
      fields = self.fields,
      cells = self.cells,
      cellsHash = self.cellsHash,
      isEdit = self.isEdit,
      isBatchOperation = self.isBatchOperation;
    // 序号
    if (isEdit && !cells.find(cell => cell.field.type == CellType.sequence)) {
      cells.unshift(Cell.generateNew(CellType.sequence));
    }
    // 添加批量操作列头
    if (isBatchOperation && !cells.find(cell => cell.field.type == CellType.batch)) {
      cells.unshift(Cell.generateNew(CellType.batch));
    }
    // 添加新增按钮列头
    if (isEdit && !cells.find(cell => cell.field.fieldId == CellType.add)) {
      cells.push(Cell.generateNew(CellType.add));
    }
    // fieldId -> cell 映射
    cells.forEach((cell, index) => {
      cellsHash[cell.field.fieldId] = cell;
      // 设置默认字段名
      if (!cell.field.name) {
        cell.field.name = "第" + index + "列";
      }
      // 序号列、批量操作列
      if (cell.type == CellType.sequence || cell.type == CellType.batch) {
        cell.width = 44;
      }
      // 新增列
      else if (cell.type == CellType.add || cell.isNew) {
        cell.width = 240;
      }
      // 常规
      else {
        let titleLength = length(cell.field.name);
        if (titleLength <= 28) {
          cell.width = titleLength * 6 + 93;
        } else {
          cell.width = 240;
        }

      }
    });
    // 计算 Cell位置、 Cell总宽度
    self.rect.scrollWidth = cells.filter(cell => cell.type == CellType.data || cell.type == CellType.add).reduce((initial, cell) => {
      cell.left = initial;
      return initial + cell.width;
    }, 0);

    // 同步 fields
    fields.splice(0, fields.length);
    cells.filter(cell => cell.type == CellType.data).forEach(cell => fields.push(cell.field));

  }

  /**
   * 执行命令
   * @param cmd
   * @param component
   */
  execute(cmd: string, component?: CellComponent): void {
    switch (cmd) {
      // 设置字段名
      case "rename":
        setTimeout(() => {
          component.element.querySelector("div.name").dispatchEvent(new MouseEvent("click"));
          component.element.querySelector("div.name").dispatchEvent(new MouseEvent("click"));
        });
        break;
      // 设置属性
      case "re-property":
        setTimeout(() => {
          component.element.querySelector("div.name").dispatchEvent(new MouseEvent("click"));
        });
        break;
      // 设置数据类型
      case "re-type":
        setTimeout(() => {
          component.element.querySelector("div.icon").dispatchEvent(new MouseEvent("click"));
        });
        break;
      // 前置插入 Cell
      case "before":
        this.cells.splice(this.cells.indexOf(component.cell), 0, Cell.generateNew(CellType.data));
        this.reset();
        break;
      // 后置插入 Cell
      case "after":
        this.cells.splice(this.cells.indexOf(component.cell) + 1, 0, Cell.generateNew(CellType.data));
        this.reset();
        break;
      // 复制
      case "copy":
        this.cells.splice(this.cells.indexOf(component.cell) + 1, 0, Cell.copy(component.cell));
        this.reset();
        break;
      // 新增
      case "add":
        this.cells.splice(this.cells.length - 1, 0, Cell.generateNew(CellType.data));
        this.reset();
        break;
      // 删除 Cell
      case "delete":
        this.cells.splice(this.cells.indexOf(component.cell), 1);
        this.reset();
        break;
    }
  }

  /**
   * 显示字段属性
   */
  onShowSetFieldPropertyPopover(options): void {
    options.context.ctrl.isSet = true;
  }

  /**
   * 隐藏字段属性
   */
  onHideSetFieldPropertyPopover(options): void {
    options.context.ctrl.isSet = false;
  }

  /**
   * 销毁 Table
   */
  ngOnDestroy(): void {
    this.unSubscription.unsubscribe();
  }

}

